﻿namespace Snipps.Controls
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;

    [TemplatePart(Name = PART_MainContent, Type = typeof(ContentPresenter))]
    [TemplatePart(Name = PART_OverlayContent, Type = typeof(ContentPresenter))]
    [TemplatePart(Name = PART_MainContentPreview, Type = typeof(Border))]
    [TemplatePart(Name = PART_Overlay, Type = typeof(FrameworkElement))]
    public class Overlay : ContentControl
    {
        private const string PART_MainContent = "PART_MainContent";

        private const string PART_OverlayContent = "PART_OverlayContent";

        private const string PART_MainContentPreview = "PART_MainContentPreview";

        private const string PART_Overlay = "PART_Overlay";

        public static readonly DependencyProperty IsOverlayVisibleProperty = DependencyProperty.Register(
            "IsOverlayVisible", typeof(bool), typeof(Overlay), new PropertyMetadata(default(bool), OnIsOverlayVisibleChanged)
            
            // new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.AffectsRender)
            );

        public static readonly DependencyProperty MainContentProperty = DependencyProperty.Register(
            "MainContent", typeof(object), typeof(Overlay), new PropertyMetadata(default(object)));

        public static readonly DependencyProperty OverlayContentProperty = DependencyProperty.Register(
            "OverlayContent", 
            typeof(object), 
            typeof(Overlay), 
            new FrameworkPropertyMetadata(default(object), FrameworkPropertyMetadataOptions.AffectsRender));

        public static readonly DependencyProperty OverlayContentTemplateProperty =
            DependencyProperty.Register(
                "OverlayContentTemplate", typeof(DataTemplate), typeof(Overlay), new PropertyMetadata(default(DataTemplate)));

        public static readonly DependencyProperty MainContentTemplateProperty = DependencyProperty.Register(
            "MainContentTemplate", typeof(DataTemplate), typeof(Overlay), new PropertyMetadata(default(DataTemplate)));

        private FrameworkElement _mainContent;

        private FrameworkElement _overlay;

        public DataTemplate OverlayContentTemplate
        {
            get
            {
                return (DataTemplate)GetValue(OverlayContentTemplateProperty);
            }

            set
            {
                SetValue(OverlayContentTemplateProperty, value);
            }
        }

        public DataTemplate MainContentTemplate
        {
            get
            {
                return (DataTemplate)GetValue(MainContentTemplateProperty);
            }

            set
            {
                SetValue(MainContentTemplateProperty, value);
            }
        }

        public bool IsOverlayVisible
        {
            get
            {
                return (bool)GetValue(IsOverlayVisibleProperty);
            }

            set
            {
                SetValue(IsOverlayVisibleProperty, value);
            }
        }

        public object MainContent
        {
            get
            {
                return GetValue(MainContentProperty);
            }

            set
            {
                SetValue(MainContentProperty, value);
            }
        }

        public object OverlayContent
        {
            get
            {
                return GetValue(OverlayContentProperty);
            }

            set
            {
                SetValue(OverlayContentProperty, value);
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            var border = GetTemplateChild(PART_MainContentPreview) as Border;
            if (border != null)
            {
                border.PreviewMouseLeftButtonDown += BorderOnPreviewMouseLeftButtonDown;
            }

            _overlay = GetTemplateChild(PART_Overlay) as FrameworkElement;
            _mainContent = GetTemplateChild(PART_MainContent) as FrameworkElement;

            UpdateOverlayVisibility();
        }

        private void BorderOnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
        {
            HideOverlay();

            // focus main content:
            if (_mainContent != null)
            {
                var tRequest = new TraversalRequest(FocusNavigationDirection.Next);
                _mainContent.MoveFocus(tRequest);
            }
        }

        public void ShowOverlay()
        {
            if (_overlay != null)
            {
                _overlay.Visibility = Visibility.Visible;
            }
        }

        public void HideOverlay()
        {
            if (_overlay != null)
            {
                _overlay.Visibility = Visibility.Collapsed;
            }
        }

        private static void OnIsOverlayVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var overlay = d as Overlay;
            if (d == null || overlay == null)
            {
                return;
            }

            overlay.UpdateOverlayVisibility();
        }

        private void UpdateOverlayVisibility()
        {
            if (IsOverlayVisible)
            {
                ShowOverlay();
            }
            else
            {
                HideOverlay();
            }
        }
    }
}